#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <struct.h>
#include <pthread.h>
#include <errno.h>
#include <termios.h>
#include <stdint.h>

//m0上报
#define ENV_LEN sizeof(struct m0_env_info)
#define CONVER_ENV_LEN sizeof(struct conver_env_info)
#define DEV_UART "/dev/ttyUSB0"
//灯
unsigned char LED_ON = 0xA1;
unsigned char LED_OFF = 0xA0;
//蜂鸣器
unsigned char ALARM_ON = 0x91;
unsigned char ALARM_OFF = 0x90;
//风扇
unsigned char FAN_ON1 = 0x81;
unsigned char FAN_ON2 = 0x82;
unsigned char FAN_ON3 = 0x83;
unsigned char FAN_OFF = 0x80;

float temperature;
float humidity;
int ill;


//函数声明
void *DataControl(void *arg);

//共享内存结构体
static struct shm_param para;

int main(int argc, char const *argv[])
{
	char buf[1090];//保存点表

	int fd_dev;
	pthread_t tid_ctl;//控制线程

	int shm_ret = -1;

	//定义内核链表结构体
	struct m0_node_list head;
	INIT_LIST_HEAD(&head.list);

	struct list_head *pos;
	struct m0_node_list *tmp;

	//共享内存
	shm_ret = shm_init(&para,"shm_equipment",1024);
	if(shm_ret < 0)
	{
		return -1;
	}

	struct std_node *node = shm_getaddr(&para);
	if(node == NULL)
	{
		return -1;
	}

	//读取点表
	int fd = open("../res/node.json",O_RDONLY);
	if(fd < 0)
	{
		printf("open error\n");
		return -1;
	}
	ssize_t ret = read(fd,buf,1090);
	if(ret<0)
	{
		printf("read error\n");
		return -1;
	}
	//反序列化
	cJSON *root = NULL;
	cJSON *item = NULL;
	cJSON *array = NULL;
	cJSON *temp = NULL;

	root = cJSON_Parse(buf);
	if(!root)
	{
		printf("Error before:[%s]\n",cJSON_GetErrorPtr());
	}
	else
	{
		item = cJSON_GetObjectItem(root,"m0");
		printf("%s\n",cJSON_Print(item));
		array = cJSON_GetObjectItem(item,"data");

		//添加链表
		for(int i=0;i<cJSON_GetArraySize(array);i++)
		{
			temp = cJSON_GetArrayItem(array,i);
			struct m0_node_list *m = (struct m0_node_list *)malloc(sizeof(struct m0_node_list));
			m->node.key = atoi(cJSON_Print(cJSON_GetObjectItem(temp,"key")));
			strcpy(m->node.name, cJSON_Print(cJSON_GetObjectItem(temp,"name")));
			m->node.type = atoi(cJSON_Print(cJSON_GetObjectItem(temp,"type")));
			list_add_tail(&m->list,&head.list);
		}

	}
	//数据上报
	int nbytes = 0;
	struct m0_env_info envinfo;
	if((fd_dev = open(DEV_UART,O_RDWR))<0)
	{
		perror("open error\n");
		return -1;
	}

	//初始化设备全关
	write(fd_dev,&LED_OFF,1);
	write(fd_dev,&FAN_OFF,1);
	write(fd_dev,&ALARM_OFF,1);

	serial_init(fd_dev);

	//控制线程
	if(pthread_create(&tid_ctl,NULL,DataControl,NULL)!=0)
	{
		perror("DataControl error");
		return -1;
	}

	while(1)
	{
		nbytes = read(fd_dev,&envinfo,ENV_LEN);
		if(nbytes == ENV_LEN)
		{
			printf("raw data ill = %d,x=%d,y=%d,z=%d\n",envinfo.ill,envinfo.x,envinfo.y,envinfo.z);

		}
		else
		{
			printf("err data");
		} 
		temperature = envinfo.temp[0]+dota_atof(envinfo.temp[1]);
		humidity = envinfo.hum[0]+dota_atof(envinfo.hum[1]);
		ill=envinfo.ill;
		printf("conver temperature = %0.2f,humidity=%0.2f,ill=%d\n",temperature,humidity,ill);

		list_for_each(pos,&head.list)
		{
			tmp = list_entry(pos,struct m0_node_list,list);
			if(tmp->node.key == 1)
			{
				node[0].key = 1;
				node[0].new_val.f_val = temperature;
			}
			else if(tmp->node.key == 2)
			{
				node[1].key = 2;
				node[1].new_val.f_val = humidity;
			}
			else if(tmp->node.key == 3)
			{
				node[2].key = 3;
				node[2].new_val.i_val = ill;
			}
			else if(tmp->node.key == 4)
			{
				node[3].key = 4;
				node[3].new_val.b_val = 0;
			}
			else if(tmp->node.key == 5)
			{
				node[4].key = 5;
				node[4].new_val.b_val = 0;
			}
			else if(tmp->node.key == 6)
			{
				node[5].key = 6;
				node[5].new_val.b_val = 0;
			}
			puts("\n");
		}
	}

	pthread_join(tid_ctl,NULL);
	close(fd);
	return 0;
}

void *DataControl(void *arg)
{
	struct msg_struct recv;
	char recv1[64]="0";
	int fd_dev;
	if((fd_dev = open(DEV_UART,O_RDWR))<0)
	{
		perror("open error\n");
		return -1;
	}
	//接收
	while(1)
	{
	if(msg_queue_recv("m0_msg",&recv,sizeof(recv),0,0)>0)
	{
		switch(recv.key)
		{
		case 1:
			m0_review(); 
			break;
		case 2:
			m0_review(); 
			break;
		case 3:
			m0_review(); 
			break;
		case 4:
			if(recv.msg_val[1]=='0')
			{
				write(fd_dev,&LED_OFF,1);
				m0_review();
			}
			else
			{
				write(fd_dev,&LED_ON,1);
				m0_review();
			}
			break;
		case 5:
			if(recv.msg_val[1]=='0')
			{
				write(fd_dev,&ALARM_OFF,1);
				m0_review(); 
			}
			else
			{
				write(fd_dev,&ALARM_ON,1);
				m0_review();
			}
			break;
		case 6:
			if(recv.msg_val[1]=='0')
			{
				write(fd_dev,&FAN_OFF,1);
				m0_review(); 
			}
			else if(recv.msg_val[1]=='1')
			{
				write(fd_dev,&FAN_ON1,1);
				m0_review(); 
			}
			else if(recv.msg_val[1]=='2')
			{
				write(fd_dev,&FAN_ON2,1);
				m0_review();
			}
			else if(recv.msg_val[1]=='3')
			{
				write(fd_dev,&FAN_ON3,1);
				m0_review(); 
			}
			break;
		}
		printf("recv from m0 data = %s\n",recv.msg_val);
		printf("key:%d\n",recv.key);
	}
	else
	{
		printf("recv error\n");
	}
	}
	pthread_exit(NULL);
}

